package com.cpp.common.utils;

import java.util.*;

public class ScoreAllocationUtils {

    /**
     * 根据题型权重和题目数量，分配每个小题的分数，确保总分为 targetTotalScore
     *
     * @param targetTotalScore 目标总分（如100）
     * @param questionCountMap 各题型对应的题目数量，如 {"single": 5, "multiple": 3}
     * @param weightMap        各题型权重，如 {"single": 0.2, "multiple": 0.3}
     * @return Map<String, List<Integer>> 每个题型下各题目的具体分数
     */
    public static Map<String, List<Integer>> allocateScores(
            int targetTotalScore,
            Map<String, Integer> questionCountMap,
            Map<String, Double> weightMap) {

        Map<String, List<Integer>> result = new LinkedHashMap<>();

        // Step 1: 计算每种题型应得的总分（按权重分配）
        Map<String, Integer> typeScoreMap = new HashMap<>();
        Set<String> types = questionCountMap.keySet();

        // 先计算每种题型的基本分数
        for (String type : types) {
            int count = questionCountMap.getOrDefault(type, 0);
            if (count <= 0) continue;

            double weight = weightMap.getOrDefault(type, 0.0);
            int allocatedScore = (int) Math.round(targetTotalScore * weight);
            typeScoreMap.put(type, allocatedScore);
        }

        // Step 2: 调整分数，保证总和为 targetTotalScore
        adjustTotalScore(targetTotalScore, typeScoreMap);

        // Step 3: 在每种题型内部均分该部分分数给每道题
        for (String type : types) {
            int count = questionCountMap.getOrDefault(type, 0);
            if (count <= 0) {
                result.put(type, Collections.emptyList());
                continue;
            }

            int totalScoreForType = typeScoreMap.getOrDefault(type, 0);
            List<Integer> scores = allocateToEachQuestion(totalScoreForType, count);
            result.put(type, scores);
        }

        return result;
    }

    /**
     * 调整各个题型的总分，使其加起来正好等于目标总分
     */
    private static void adjustTotalScore(int targetTotal, Map<String, Integer> scoreMap) {
        List<String> keys = new ArrayList<>(scoreMap.keySet());
        int currentTotal = scoreMap.values().stream().mapToInt(Integer::intValue).sum();

        int diff = targetTotal - currentTotal;

        if (diff == 0) return;

        // 增加或减少最后一个题型的分数来调整总分
        if (!keys.isEmpty()) {
            String lastKey = keys.get(keys.size() - 1);
            int newValue = scoreMap.get(lastKey) + diff;
            if (newValue < 0) newValue = 0; // 不允许负数
            scoreMap.put(lastKey, newValue);
        }
    }

    /**
     * 将某个题型的总分平均分配到每道题上（带余数补足）
     */
    private static List<Integer> allocateToEachQuestion(int totalScore, int questionCount) {
        List<Integer> scores = new ArrayList<>();
        if (questionCount <= 0) return scores;

        int avg = totalScore / questionCount;
        int remainder = totalScore % questionCount;

        for (int i = 0; i < questionCount; i++) {
            scores.add(avg + (i < remainder ? 1 : 0));
        }

        return scores;
    }
}